"""
Copyright 2012 Wieser Dietmar, Margit Mutschlechner.

This file is part of Multimedia Social Networking Platform.

Multimedia Social Networking Platform is free software: 
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Multimedia Social Networking Platform is distributed
in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Multimedia Social Networking Platform.  
If not, see <http://www.gnu.org/licenses/>.

"""

import traceback
from msnp.persistence import PersistenceController
from msnp.service.network import BackupController
from msnp.model.PTPModel import User, BackupContent
from msnp.model import PTPModel
from msnp.logger import Logger

"""Module to validate the user credentials.

Contains functions to validate the authentication process (both login and register)."""

def validateAuthentication(identity, isLogin):
    """This function validates the user credentials.
    
    Args:
        identity: the authenticating identity (PeerInfo instance)
        isLogin: a boolean determining whether the underlying authentication process is a login or a registration.
    
    Returns:
        The return value is defined by PTPModel.ReturnType and can be one of the following values:
        SUCCESSFUL, AUTHENTICATION_NO_PASSWORD, ERROR, LOGIN_WRONG_PASSWORD, LOGIN_WRONG_USERNAME, REGISTER_NAME_NOT_AVAILABLE
    """
    
    try:
        name = identity.getName()
        password = identity.getPassword()
        if name != None:
            if password != None:
                if isLogin:
                    return __validateLoginCredentials(name, password)
                else:
                    return __processAndValidateRegisterCredentials(name, password)
            else:
                Logger.info('no password set during authentication')
                return PTPModel.ReturnType.AUTHENTICATION_NO_PASSWORD
        else:
            Logger.info('Error: name is None during validation of authentication')
            return PTPModel.ReturnType.ERROR
    except:
        Logger.info("Exception during authentication validation")
        Logger.info(traceback.format_exc())
    return PTPModel.ReturnType.ERROR


def __validateLoginCredentials(name, password):
    """This function validates the login credentials.
    
    Args:
        name: the user name (string)
        password: the password (string)
    
    Returns:
        The return value is defined by PTPModel.ReturnType and can be one of the following values:
        SUCCESSFUL, ERROR, LOGIN_WRONG_PASSWORD, LOGIN_WRONG_USERNAME
    """
    
    user = PersistenceController.selectUserImResponsibleForUsername(name)
    if user != None:
        #security check
        if (user.getUsername() == name):
            if(user.getPassword() == password):
                return PTPModel.ReturnType.SUCCESSFUL
            else:
                return PTPModel.ReturnType.LOGIN_WRONG_PASSWORD
        else:
            Logger.info('Error during validation of login credentials. wrong user fetched from database... FATAL!!! :)')
            return PTPModel.ReturnType.ERROR
    else:
        #User does not exist in database.
        return PTPModel.ReturnType.LOGIN_WRONG_USERNAME
    
    
def __processAndValidateRegisterCredentials(name, password):
    """This function validates the registration process.
    
    Args:
        name: the user name (string)
        password: the password (string)
    
    Returns:
        The return value is defined by PTPModel.ReturnType and can be one of the following values:
        SUCCESSFUL, REGISTER_NAME_NOT_AVAILABLE, ERROR
    """
    
    user = PersistenceController.selectUserImResponsibleForUsername(name)
    if user != None:
        #name is already assigned to another person
        return PTPModel.ReturnType.REGISTER_NAME_NOT_AVAILABLE
    else:
        #register new user -> i'm responsible for this new user
        user = User(name, None, password, None)
        backupContent = BackupContent(None, [user], None, None, PTPModel.BackupType.UPDATE)
        if BackupController.processBackup(backupContent):
            return PTPModel.ReturnType.SUCCESSFUL
        else:
            return PTPModel.ReturnType.ERROR

